home *** CD-ROM | disk | FTP | other *** search
/ SPACE 1 / SPACE - Library 1 - Volume 1.iso / misc~1 / 198 / viscalc / lex.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-01-10  |  8.5 KB  |  348 lines

  1. /*    SC    A Spreadsheet Calculator
  2.  
  3.  *        Lexical analyser
  4.  
  5.  *
  6.  
  7.  *        original by James Gosling, September 1982
  8.  
  9.  *        modifications by Mark Weiser and Bruce Israel,
  10.  
  11.  *            University of Maryland
  12.  
  13.  *
  14.  
  15.  *              More mods Robert Bond, 12/86
  16.  
  17.  *        Major mods to run on VMS and AMIGA, 1/17/87
  18.  
  19.  *
  20.  
  21.  */
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29. #include "sc.h"
  30.  
  31. #include <ctype.h>
  32.  
  33. #ifdef VMS
  34.  
  35. #include "y_tab.h"
  36.  
  37. #else
  38.  
  39. #ifdef TOS
  40.  
  41. #include "y_tab.h"
  42.  
  43. #else
  44.  
  45. #include "y.tab.h"
  46.  
  47. #endif
  48.  
  49. #endif
  50.  
  51.  
  52.  
  53. extern char *malloc();
  54.  
  55. char *strtof();
  56.  
  57.  
  58.  
  59. struct key {
  60.  
  61.     char *key;
  62.  
  63.     int val;
  64.  
  65. };
  66.  
  67.  
  68.  
  69. struct key experres[] = {
  70.  
  71. #include "experres.h"
  72.  
  73.     0, 0};
  74.  
  75.  
  76.  
  77. struct key statres[] = {
  78.  
  79. #include "statres.h"
  80.  
  81.     0, 0};
  82.  
  83.  
  84.  
  85. #define ctl(x) ('x'&037)
  86.  
  87.  
  88.  
  89. yylex () {
  90.  
  91.     register char *p = line+linelim;
  92.  
  93.     int ret = -1;
  94.  
  95.     while (isspace(*p)) p++;
  96.  
  97.     if (*p==0) ret = -1;
  98.  
  99.     else if (isalpha(*p)) {
  100.  
  101.     char *tokenst = p;
  102.  
  103.     register tokenl;
  104.  
  105.     register struct key *tbl;
  106.  
  107.     while (isalpha(*p)) p++;
  108.  
  109.     if (p-tokenst <= 2) { /* a COL is 1 or 2 char alpha */
  110.  
  111.         register  col;
  112.  
  113.         ret = COL;
  114.  
  115.         col = ((tokenst[0] & 0137) - 'A');
  116.  
  117.         if (p == tokenst+2)
  118.  
  119.         col = (col + 1)*26 + ((tokenst[1] & 0137) - 'A');
  120.  
  121.         yylval.ival =  col;
  122.  
  123.     } else {
  124.  
  125.         ret = WORD;
  126.  
  127.         tokenl = p-tokenst;
  128.  
  129.         for (tbl = linelim ? experres : statres; tbl->key; tbl++)
  130.  
  131.             if (((tbl->key[0]^tokenst[0])&0137)==0
  132.  
  133.              && tbl->key[tokenl]==0) {
  134.  
  135.             register i = 1;
  136.  
  137.             while (i<tokenl && ((tokenst[i]^tbl->key[i])&0137)==0)
  138.  
  139.                 i++;
  140.  
  141.             if (i>=tokenl) {
  142.  
  143.                 ret = tbl->val;
  144.  
  145.                 break;
  146.  
  147.             }
  148.  
  149.             }
  150.  
  151.         if (ret==WORD) { 
  152.  
  153.         linelim = p-line;
  154.  
  155.         yyerror ("Unintelligible word");
  156.  
  157.         }
  158.  
  159.     }
  160.  
  161.     } else if ((*p == '.') || isdigit(*p)) {
  162.  
  163.     register long v = 0;
  164.  
  165.     char *nstart = p;
  166.  
  167.     if (*p != '.') {
  168.  
  169.         do v = v*10 + (*p-'0');
  170.  
  171.         while (isdigit(*++p));
  172.  
  173.     }
  174.  
  175.     if (*p=='.' || *p == 'e' || *p == 'E') {
  176.  
  177.         ret = FNUMBER;
  178.  
  179.         p = strtof(nstart, &yylval.fval);
  180.  
  181.     } else {
  182.  
  183.             if((int)v != v)
  184.  
  185.             {
  186.  
  187.                 ret = FNUMBER;
  188.  
  189.                 yylval.fval = v;
  190.  
  191.             }
  192.  
  193.             else
  194.  
  195.             {
  196.  
  197.  
  198.  
  199.                 ret = NUMBER;
  200.  
  201.                 yylval.ival = v;
  202.  
  203.             }
  204.  
  205.     }
  206.  
  207.     } else if (*p=='"') {
  208.  
  209.     /* This storage is never freed.  Oh well.  -MDW */
  210.  
  211.     char *ptr;
  212.  
  213.         ptr = p+1;
  214.  
  215.         while(*ptr && *ptr++ != '"');
  216.  
  217.         ptr = (char *)malloc((unsigned)(ptr-p));
  218.  
  219.     yylval.sval = ptr;
  220.  
  221.     p += 1;
  222.  
  223.     while (*p && *p!='"') *ptr++ = *p++;
  224.  
  225.     *ptr = 0;
  226.  
  227.     if (*p) p += 1;
  228.  
  229.     ret = STRING;
  230.  
  231.     } else if (*p=='[') {
  232.  
  233.     while (*p && *p!=']') p++;
  234.  
  235.     if (*p) p++;
  236.  
  237.     linelim = p-line;
  238.  
  239.     return yylex();
  240.  
  241.     } else ret = *p++;
  242.  
  243.     linelim = p-line;
  244.  
  245.     return ret;
  246.  
  247. }
  248.  
  249.  
  250.  
  251. #define N_KEY 26
  252.  
  253.  
  254.  
  255. struct key_map {
  256.  
  257.     char *k_str;
  258.  
  259.     char k_val;
  260.  
  261.     char k_index;
  262.  
  263. }; 
  264.  
  265.  
  266.  
  267. struct key_map km[N_KEY];
  268.  
  269.  
  270.  
  271. initkbd()
  272.  
  273. {
  274.  
  275.     int i;
  276.  
  277.  
  278.  
  279.     /* cursor set mode */
  280.  
  281.     km[0].k_str  = "\033OD"; km[0].k_val  = ctl(b);
  282.  
  283.     km[1].k_str  = "\033OC"; km[1].k_val  = ctl(f);
  284.  
  285.     km[2].k_str  = "\033OA"; km[2].k_val  = ctl(p);
  286.  
  287.     km[3].k_str  = "\033OB"; km[3].k_val  = ctl(n);
  288.  
  289.     /* cursor reset mode */
  290.  
  291.     km[4].k_str  = "\033[D"; km[4].k_val  = ctl(b);
  292.  
  293.     km[5].k_str  = "\033[C"; km[5].k_val  = ctl(f);
  294.  
  295.     km[6].k_str  = "\033[A"; km[6].k_val  = ctl(p);
  296.  
  297.     km[7].k_str  = "\033[B"; km[7].k_val  = ctl(n);
  298.  
  299.     /* CSI arrows */
  300.  
  301.     km[8].k_str  = "\233D";  km[8].k_val  = ctl(b);
  302.  
  303.     km[9].k_str  = "\233C";  km[9].k_val  = ctl(f);
  304.  
  305.     km[10].k_str = "\233A";  km[10].k_val = ctl(p);
  306.  
  307.     km[11].k_str = "\233B";  km[11].k_val = ctl(n);
  308.  
  309.     /* application keypad mode */
  310.  
  311.     km[12].k_str = "\033Op"; km[12].k_val = '0';
  312.  
  313.     km[13].k_str = "\033Oq"; km[13].k_val = '1';
  314.  
  315.     km[14].k_str = "\033Or"; km[14].k_val = '2';
  316.  
  317.     km[15].k_str = "\033Os"; km[15].k_val = '3';
  318.  
  319.     km[16].k_str = "\033Ot"; km[16].k_val = '4';
  320.  
  321.     km[17].k_str = "\033Ou"; km[17].k_val = '5';
  322.  
  323.     km[18].k_str = "\033Ov"; km[18].k_val = '6';
  324.  
  325.     km[19].k_str = "\033Ow"; km[19].k_val = '7';
  326.  
  327.     km[20].k_str = "\033Ox"; km[20].k_val = '8';
  328.  
  329.     km[21].k_str = "\033Oy"; km[21].k_val = '9';
  330.  
  331.     km[22].k_str = "\033Om"; km[22].k_val = '-';
  332.  
  333.     km[23].k_str = "\033Ol"; km[23].k_val = ',';
  334.  
  335.     km[24].k_str = "\033On"; km[24].k_val = '.';
  336.  
  337.     km[25].k_str = "\033OM"; km[25].k_val = ctl(m);
  338.  
  339. }
  340.  
  341.  
  342.  
  343. nmgetch() 
  344.  
  345. {
  346.  
  347.     register int c;
  348.  
  349.     register struct key_map *kp;
  350.  
  351.     register struct key_map *biggest;
  352.  
  353.     register int i;
  354.  
  355.     int almost;
  356.  
  357.     int maybe;
  358.  
  359.  
  360.  
  361.     static char dumpbuf[10];
  362.  
  363.     static char *dumpindex;
  364.  
  365.  
  366.  
  367.     void timeout();
  368.  
  369.  
  370.  
  371.     if (dumpindex && *dumpindex)
  372.  
  373.         return (*dumpindex++);
  374.  
  375.  
  376.  
  377.     c = ttgetc();
  378.  
  379.     biggest = 0;
  380.  
  381.     almost = 0;
  382.  
  383.  
  384.  
  385.     for (kp = &km[0]; kp < &km[N_KEY]; kp++) {
  386.  
  387.     if (!kp->k_str)
  388.  
  389.         continue;
  390.  
  391.     if (c == (kp->k_str[kp->k_index] & 0xFF)) {
  392.  
  393.         almost = 1;
  394.  
  395.         kp->k_index++;
  396.  
  397.         if (kp->k_str[kp->k_index] == 0) {
  398.  
  399.         c = kp->k_val;
  400.  
  401.                    for (kp = &km[0]; kp < &km[N_KEY]; kp++)
  402.  
  403.                 kp->k_index = 0;
  404.  
  405.             return(c);
  406.  
  407.         }
  408.  
  409.     }
  410.  
  411.     if (!biggest && kp->k_index)
  412.  
  413.         biggest = kp;
  414.  
  415.         else if (kp->k_index && biggest->k_index < kp->k_index)
  416.  
  417.         biggest = kp;
  418.  
  419.     }
  420.  
  421.  
  422.  
  423.     if (almost) return(nmgetch());
  424.  
  425.  
  426.  
  427.     if (biggest) {
  428.  
  429.     for (i = 0; i<biggest->k_index; i++) 
  430.  
  431.         dumpbuf[i] = biggest->k_str[i];
  432.  
  433.     dumpbuf[i++] = c;
  434.  
  435.     dumpbuf[i] = 0;
  436.  
  437.     dumpindex = &dumpbuf[1];
  438.  
  439.            for (kp = &km[0]; kp < &km[N_KEY]; kp++)
  440.  
  441.         kp->k_index = 0;
  442.  
  443.     return (dumpbuf[0]);
  444.  
  445.     }
  446.  
  447.  
  448.  
  449.     return(c);
  450.  
  451. }
  452.  
  453.  
  454.  
  455.  
  456.  
  457. int dbline;
  458.  
  459.  
  460.  
  461. debug (fmt, a, b, c) {
  462.  
  463.     move(2+(dbline++%22),80-60);
  464.  
  465.     printw(fmt,a,b,c);
  466.  
  467.     clrtoeol();
  468.  
  469. }
  470.  
  471.  
  472.  
  473. /*
  474.  
  475.  * This converts a floating point number of the form
  476.  
  477.  * [s]ddd[.d*][esd*]  where s can be a + or - and e is E or e.
  478.  
  479.  * to floating point. 
  480.  
  481.  * p is advanced.
  482.  
  483.  */
  484.  
  485.  
  486.  
  487. char *
  488.  
  489. strtof(p, res)
  490.  
  491. register char *p;
  492.  
  493. double *res;
  494.  
  495. {
  496.  
  497.     double acc;
  498.  
  499.     int sign;
  500.  
  501.     double fpos;
  502.  
  503.     int exp;
  504.  
  505.     int exps;
  506.  
  507.  
  508.  
  509.     acc = 0.0;
  510.  
  511.     sign = 1;
  512.  
  513.     exp = 0;
  514.  
  515.     exps = 1;
  516.  
  517.     if (*p == '+')
  518.  
  519.         p++;
  520.  
  521.     else if (*p == '-') {
  522.  
  523.         p++;
  524.  
  525.         sign = -1;
  526.  
  527.     }
  528.  
  529.     while (isdigit(*p)) {
  530.  
  531.         acc = acc * 10.0 + (double)(*p - '0');
  532.  
  533.         p++;
  534.  
  535.     }
  536.  
  537.     if (*p == 'e' || *p == 'E') {
  538.  
  539.         p++;
  540.  
  541.         if (*p == '+')
  542.  
  543.         p++;
  544.  
  545.         else if (*p == '-') {
  546.  
  547.         p++;
  548.  
  549.         exps = -1;
  550.  
  551.         }
  552.  
  553.         while(isdigit(*p)) {
  554.  
  555.         exp = exp * 10 + (*p - '0');
  556.  
  557.         p++;
  558.  
  559.         }
  560.  
  561.     }
  562.  
  563.     if (*p == '.') {
  564.  
  565.     fpos = 1.0/10.0;
  566.  
  567.     p++;
  568.  
  569.     while(isdigit(*p)) {
  570.  
  571.         acc += (*p - '0') * fpos;
  572.  
  573.         fpos *= 1.0/10.0;
  574.  
  575.         p++;
  576.  
  577.     }
  578.  
  579.     }
  580.  
  581.     if (*p == 'e' || *p == 'E') {
  582.  
  583.     exp = 0;
  584.  
  585.     exps = 1;
  586.  
  587.         p++;
  588.  
  589.     if (*p == '+')
  590.  
  591.         p++;
  592.  
  593.     else if (*p == '-') {
  594.  
  595.         p++;
  596.  
  597.         exps = -1;
  598.  
  599.     }
  600.  
  601.     while(isdigit(*p)) {
  602.  
  603.         exp = exp * 10 + (*p - '0');
  604.  
  605.         p++;
  606.  
  607.     }
  608.  
  609.     }
  610.  
  611.     if (exp) {
  612.  
  613.     if (exps > 0)
  614.  
  615.         while (exp--)
  616.  
  617.         acc *= 10.0;
  618.  
  619.     else
  620.  
  621.         while (exp--)
  622.  
  623.         acc *= 1.0/10.0;
  624.  
  625.     }
  626.  
  627.     if (sign > 0)
  628.  
  629.         *res = acc;
  630.  
  631.     else
  632.  
  633.     *res = -acc;
  634.  
  635.  
  636.  
  637.     return(p);
  638.  
  639. }
  640.  
  641.  
  642.  
  643. help () {
  644.  
  645.     move(2,0);
  646.  
  647.     clrtobot();
  648.  
  649.     dbline = 0;
  650.  
  651.     debug ("                 Cursor cmds:");
  652.  
  653.     debug ("  ^n j next row       ^p k prev. row      ^g erase cmd");
  654.  
  655.     debug ("  ^f l fwd col        ^b h back col       ^r redraw screen");
  656.  
  657.     debug ("   0 $ first, end col");
  658.  
  659.     debug ("                 Cell cmds:");
  660.  
  661.     debug (" \" < > enter label       = enter value     x clear cell");
  662.  
  663.     debug ("     c copy cell         m mark cell      ^t line 1 on/off");  
  664.  
  665.     debug ("    ^a type value       ^e type expr.     ^v type vbl name");
  666.  
  667.     debug ("                 Row, Column cmds:");
  668.  
  669.     debug (" ar ac dup           ir ic insert      sr sc show");
  670.  
  671.     debug (" dr dc delete        zr zc hide        pr pc pull");
  672.  
  673.     debug (" vr vc value only        f format");
  674.  
  675.     debug ("                 File cmds:");
  676.  
  677.     debug ("     G get database      M merge database  T write tbl fmt");
  678.  
  679.     debug ("     P put database      W write listing");
  680.  
  681.     debug ("                 Misc. cmds:");
  682.  
  683.     debug (" ^c, q quit              / copy region    pm pull (merge)");
  684.  
  685.     debug ("                 Expression Operators");
  686.  
  687.     debug ("  +-*/ arithmetic     ?e:e conditional   & | booleans");
  688.  
  689.     debug (" < = > relations     <= >= relations      != relations");
  690.  
  691.     debug ("       @sum(v1:v2)         @avg(v1:v2)       @prod(v1:v2)");
  692.  
  693. }
  694.  
  695.